package org.balthie.demo.opensource.org.codehaus.plexus.compiler.util.scan;


import java.io.File;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.balthie.demo.opensource.org.codehaus.plexus.compiler.util.scan.mapping.SourceMapping;
import org.balthie.demo.opensource.org.codehaus.plexus.compiler.util.scan.mapping.SuffixMapping;

/**
 * @author jdcasey
 */
public class StaleSourceScanner
    extends AbstractSourceInclusionScanner
{
    public static void main(String[] args) throws Exception
    {
        Set<String> includes = null;
        if (includes == null || includes.isEmpty()) {
            includes = Collections.singleton("**/*.groovy");
        }
        Set<String> excludes = new HashSet<String>();
//        excludes.add("**/*");
        
        StaleSourceScanner  scanner = new StaleSourceScanner(0, includes, excludes);
        scanner.addSourceMapping(new SuffixMapping(".groovy", ".class"));
        scanner.addSourceMapping(new SuffixMapping(".java", ".class"));
        
        File sourceDir = new File("E:\\balthie-git\\viomi-gitlab\\viomi-java-architecture\\Modularity-Architecture-trunk\\component-batch\\src\\test\\java");
        File outputDir = new File("E:\\balthie-git\\viomi-gitlab\\viomi-java-architecture\\Modularity-Architecture-trunk\\component-batch\\src\\mytest\\java");
        Set<File> files = scanner.getIncludedSources(sourceDir,  outputDir);
        
        files.stream().forEach(System.out::println);
        
    }    
    
    private final long lastUpdatedWithinMsecs;

    private final Set<String> sourceIncludes;

    private final Set<String> sourceExcludes;

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    public StaleSourceScanner()
    {
        this( 0, Collections.singleton( "**/*" ), Collections.<String>emptySet() );
    }

    public StaleSourceScanner( long lastUpdatedWithinMsecs )
    {
        this( lastUpdatedWithinMsecs, Collections.singleton( "**/*" ), Collections.<String>emptySet() );
    }

    public StaleSourceScanner( long lastUpdatedWithinMsecs, Set<String> sourceIncludes, Set<String> sourceExcludes )
    {
        this.lastUpdatedWithinMsecs = lastUpdatedWithinMsecs;

        this.sourceIncludes = sourceIncludes;

        this.sourceExcludes = sourceExcludes;
    }

    // ----------------------------------------------------------------------
    // SourceInclusionScanner Implementation
    // ----------------------------------------------------------------------

    public Set<File> getIncludedSources( File sourceDir, File targetDir )
        throws Exception
    {
        List<SourceMapping> srcMappings = getSourceMappings();

        if ( srcMappings.isEmpty() )
        {
            return Collections.emptySet();
        }

        String[] potentialIncludes = scanForSources( sourceDir, sourceIncludes, sourceExcludes );

        Set<File> matchingSources = new HashSet<File>();

        for ( String path : potentialIncludes )
        {
            File sourceFile = new File( sourceDir, path );

            staleSourceFileTesting:
            for ( SourceMapping mapping : srcMappings )
            {
                Set<File> targetFiles = mapping.getTargetFiles( targetDir, path );

                // never include files that don't have corresponding target mappings.
                // the targets don't have to exist on the filesystem, but the
                // mappers must tell us to look for them.
                for ( File targetFile : targetFiles )
                {
                    if ( !targetFile.exists() || ( targetFile.lastModified() + lastUpdatedWithinMsecs
                        < sourceFile.lastModified() ) )
                    {
                        matchingSources.add( sourceFile );
                        break staleSourceFileTesting;
                    }
                }
            }
        }

        return matchingSources;
    }
}
